Skip to content

feat: mkdocs/readthedocs#22

Open
msto wants to merge 3 commits intomainfrom
ms_mkdocs
Open

feat: mkdocs/readthedocs#22
msto wants to merge 3 commits intomainfrom
ms_mkdocs

Conversation

@msto
Copy link
Copy Markdown
Collaborator

@msto msto commented Feb 20, 2026

Summary by CodeRabbit

Release Notes

  • Documentation

    • Added comprehensive documentation site with Read the Docs integration and PR preview support.
    • Added user guide documenting schema definition, reading, and writing with Metric models.
    • Added API reference documentation for core classes.
    • Included contributing guidelines in documentation.
  • Chores

    • Added documentation build and serve tasks.
    • Added documentation dependencies.

@nh13
Copy link
Copy Markdown
Collaborator

nh13 commented Apr 8, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 8, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 8, 2026

📝 Walkthrough

Walkthrough

This pull request introduces comprehensive documentation infrastructure for the fgmetric project, including MkDocs configuration, Read the Docs setup, GitHub Actions workflow for PR previews, API documentation pages, user guides, and documentation-related dependencies and build tasks.

Changes

Cohort / File(s) Summary
Documentation Build Configuration
mkdocs.yml, .readthedocs.yaml, .github/workflows/docs.yml
Adds MkDocs site configuration with Material theme, markdown extensions, and mkdocstrings plugin; Read the Docs build configuration using Ubuntu 24.04, Python 3.12, and uv toolchain; GitHub Actions workflow for Read the Docs PR previews triggered on docs/** and config file changes.
Project Configuration & Dependencies
pyproject.toml
Adds documentation URL reference, new docs dependency group with mkdocs packages, and Poe tasks for docs-build and docs-serve.
API Documentation Pages
docs/api/metric.md, docs/api/metric_writer.md
Adds API reference documentation for Metric and MetricWriter classes using mkdocstrings directives with selective member exposure.
User Guides & Index
docs/index.md, docs/guide.md, docs/contributing.md
Adds main documentation page with badges and quick-start examples, comprehensive user guide covering Metric schema definition, reading/writing operations, list/categorical field handling, and contributing guidelines inclusion.
Project Metadata
README.md
Adds Read the Docs status badge linking to stable documentation.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 With whiskers twitched and joy so bright,
I've woven docs that gleam with light!
From index home to API's call,
MkDocs stands to serve it all—
Read the Docs shall host with care,
Knowledge blooming everywhere! 📚✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: mkdocs/readthedocs' accurately reflects the main change in the changeset—the addition of MkDocs and ReadTheDocs documentation support infrastructure.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ms_mkdocs

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (4)
.github/workflows/docs.yml (1)

19-19: Pin third-party action to a commit SHA.

Line 19 uses a mutable tag (@v1), which creates a supply-chain risk. GitHub's security guidance recommends pinning to a full commit SHA for reproducibility and safety.

💡 Suggested fix
-      - uses: readthedocs/actions/preview@v1
+      - uses: readthedocs/actions/preview@<full_commit_sha>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/docs.yml at line 19, Replace the mutable action reference
"readthedocs/actions/preview@v1" with a pinned commit SHA for that action (e.g.,
"readthedocs/actions/preview@<full-commit-sha>"); update the workflow step that
uses readthedocs/actions/preview so it references the specific full commit SHA
to ensure immutability and supply-chain safety, and verify the SHA matches the
upstream repo's commit for the desired v1 release before committing.
.readthedocs.yaml (1)

10-11: Pin uv to a specific version in .readthedocs.yaml.

Lines 10–11 use asdf install/global uv latest, which causes non-deterministic builds. Commit a .tool-versions file to your repo with a pinned version (e.g., uv 0.4.4), then update the YAML to install without latest so it reads the pinned version:

💡 Suggested fix
-      - asdf install uv latest
-      - asdf global uv latest
+      - asdf install uv
+      - asdf global uv 0.4.4

Alternatively, commit .tool-versions to your repo with uv 0.4.4 and use asdf install uv (omit version in YAML).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.readthedocs.yaml around lines 10 - 11, The YAML uses non-deterministic
"asdf install uv latest" / "asdf global uv latest"; pin the uv tool instead by
adding a .tool-versions file to the repo containing the uv version (e.g., "uv
0.4.4") and update the .readthedocs.yaml lines that call asdf to remove "latest"
(either call "asdf install uv" so it reads .tool-versions, or explicitly use the
pinned version like "asdf install uv 0.4.4" and "asdf global uv 0.4.4").
docs/guide.md (2)

103-109: Document the single-character constraint for collection_delimiter.

Lines [103]-[109] show customization but omit that collection_delimiter must be exactly one character (enforced in fgmetric/collections/_delimited_list.py, Lines 90-95).

Proposed change
-The list delimiter defaults to `,` but can be customized per-metric with the `collection_delimiter` class variable:
+The list delimiter defaults to `,` but can be customized per-metric with the `collection_delimiter` class variable (must be a single character):
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/guide.md` around lines 103 - 109, Update the docs to state that the
class variable collection_delimiter must be exactly one character
(single-character string) — this constraint is enforced by the DelimitedList
validator in fgmetric.collections._delimited_list.py (the code that validates
collection_delimiter and raises on invalid values). Mention that the default is
",", that you can override it per-metric by setting collection_delimiter = ";"
in the Metric subclass, and note that multi-character delimiters will be
rejected by the validator.

113-132: Call out Counter modeling constraints explicitly.

This section is solid, but it should mention current constraints: one Counter[...] field per model, non-optional Counter, and Counter[T] where T is StrEnum (fgmetric/collections/_counter_pivot_table.py, Lines 30-87).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/guide.md` around lines 113 - 132, Update the docs to explicitly state
the Counter modeling constraints: a model may have at most one Counter[...]
field (one Counter field per Metric), the Counter field must be non-optional
(not Optional[Counter[...]]) and the Counter generic type parameter must be a
StrEnum (i.e., use Counter[StrEnum] like Counter[Base]); reference the
implementation enforcement in the fgmetric.collections._counter_pivot_table
module and mention the symbols Counter, Metric, StrEnum so readers know where
the behavior is enforced and what signatures are required.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/docs.yml:
- Around line 5-6: The workflow only triggers on new PRs because the
pull_request trigger's types list contains only "opened"; update the
pull_request trigger (the types: setting) to include "synchronize" alongside
"opened" so subsequent commits to the PR retrigger the docs preview workflow and
keep preview data fresh.

In `@docs/guide.md`:
- Around line 67-77: The example uses AlignmentMetric and Path but only imports
MetricWriter, so make the snippet self-contained by either (A) adding the
missing import "from pathlib import Path", importing or defining AlignmentMetric
(e.g., declare class AlignmentMetric(Metric) with fields read_name,
mapping_quality, is_duplicate=False and import Metric from fgmetric) before
using MetricWriter, or (B) if AlignmentMetric is defined elsewhere, add an
explicit "from <module> import AlignmentMetric" import; ensure the metric class
name AlignmentMetric and the Path import are present so
MetricWriter(AlignmentMetric, Path("output.tsv")) and writer.writeall(metrics)
work when copy/pasted.

In `@mkdocs.yml`:
- Line 2: Replace the hardcoded site_url value with the Read the Docs canonical
URL environment variable: update the mkdocs configuration so that the site_url
key uses the READTHEDOCS_CANONICAL_URL environment variable (e.g., set site_url
to the environment variable reference) instead of the fixed
"https://fgmetric.readthedocs.io/en/stable/" so MkDocs emits correct canonical
links for versioned and preview builds.

---

Nitpick comments:
In @.github/workflows/docs.yml:
- Line 19: Replace the mutable action reference "readthedocs/actions/preview@v1"
with a pinned commit SHA for that action (e.g.,
"readthedocs/actions/preview@<full-commit-sha>"); update the workflow step that
uses readthedocs/actions/preview so it references the specific full commit SHA
to ensure immutability and supply-chain safety, and verify the SHA matches the
upstream repo's commit for the desired v1 release before committing.

In @.readthedocs.yaml:
- Around line 10-11: The YAML uses non-deterministic "asdf install uv latest" /
"asdf global uv latest"; pin the uv tool instead by adding a .tool-versions file
to the repo containing the uv version (e.g., "uv 0.4.4") and update the
.readthedocs.yaml lines that call asdf to remove "latest" (either call "asdf
install uv" so it reads .tool-versions, or explicitly use the pinned version
like "asdf install uv 0.4.4" and "asdf global uv 0.4.4").

In `@docs/guide.md`:
- Around line 103-109: Update the docs to state that the class variable
collection_delimiter must be exactly one character (single-character string) —
this constraint is enforced by the DelimitedList validator in
fgmetric.collections._delimited_list.py (the code that validates
collection_delimiter and raises on invalid values). Mention that the default is
",", that you can override it per-metric by setting collection_delimiter = ";"
in the Metric subclass, and note that multi-character delimiters will be
rejected by the validator.
- Around line 113-132: Update the docs to explicitly state the Counter modeling
constraints: a model may have at most one Counter[...] field (one Counter field
per Metric), the Counter field must be non-optional (not Optional[Counter[...]])
and the Counter generic type parameter must be a StrEnum (i.e., use
Counter[StrEnum] like Counter[Base]); reference the implementation enforcement
in the fgmetric.collections._counter_pivot_table module and mention the symbols
Counter, Metric, StrEnum so readers know where the behavior is enforced and what
signatures are required.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: eb5ddc56-3b3f-474a-99e1-9018391de1a5

📥 Commits

Reviewing files that changed from the base of the PR and between be34334 and d79ef22.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (10)
  • .github/workflows/docs.yml
  • .readthedocs.yaml
  • README.md
  • docs/api/metric.md
  • docs/api/metric_writer.md
  • docs/contributing.md
  • docs/guide.md
  • docs/index.md
  • mkdocs.yml
  • pyproject.toml

Comment on lines +5 to +6
types:
- opened
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

For GitHub Actions pull_request_target workflows, which event types are needed so jobs rerun when new commits are pushed to an existing PR?

💡 Result:

To have a pull_request_target workflow re-run when new commits are pushed to an existing PR, you need the synchronize activity type (that’s the PR action GitHub sends on new commits). (docs.github.com)

If you’re explicitly setting types:, include at least:

on:
  pull_request_target:
    types: [opened, synchronize, reopened]

(If you omit types, GitHub’s default for pull_request_target already includes opened, synchronize, and reopened.) (docs.github.com)

Citations:


Preview link won't refresh after new PR commits.

Line 6 listens only to opened, so later synchronize updates won't retrigger this workflow and preview data can go stale.

💡 Suggested fix
 on:
   pull_request_target:
     types:
       - opened
+      - synchronize
+      - reopened
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/docs.yml around lines 5 - 6, The workflow only triggers on
new PRs because the pull_request trigger's types list contains only "opened";
update the pull_request trigger (the types: setting) to include "synchronize"
alongside "opened" so subsequent commits to the PR retrigger the docs preview
workflow and keep preview data fresh.

Comment thread docs/guide.md
Comment on lines +67 to +77
```python
from fgmetric import MetricWriter

metrics = [
AlignmentMetric(read_name="read1", mapping_quality=60),
AlignmentMetric(read_name="read2", mapping_quality=30, is_duplicate=True),
]

with MetricWriter(AlignmentMetric, Path("output.tsv")) as writer:
writer.writeall(metrics)
```
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

cd "$(git rev-parse --show-toplevel)" && cat -n docs/guide.md | sed -n '67,77p'

Repository: fg-labs/fgmetric

Length of output: 436


🏁 Script executed:

cd "$(git rev-parse --show-toplevel)" && rg "class AlignmentMetric" --type python

Repository: fg-labs/fgmetric

Length of output: 90


🏁 Script executed:

cd "$(git rev-parse --show-toplevel)" && rg "class AlignmentMetric"

Repository: fg-labs/fgmetric

Length of output: 313


🏁 Script executed:

cd "$(git rev-parse --show-toplevel)" && cat -n fgmetric/__init__.py

Repository: fg-labs/fgmetric

Length of output: 240


🏁 Script executed:

cd "$(git rev-parse --show-toplevel)" && cat -n docs/guide.md | sed -n '1,67p' | tail -20

Repository: fg-labs/fgmetric

Length of output: 614


🏁 Script executed:

cd "$(git rev-parse --show-toplevel)" && rg "AlignmentMetric" docs/guide.md -B 5 | head -50

Repository: fg-labs/fgmetric

Length of output: 949


Make the writing example self-contained.

Lines 75-76 use AlignmentMetric and Path, but the snippet only imports MetricWriter. Copy/pasting this block alone will fail.

Proposed change
 ```python
+from pathlib import Path
+from fgmetric import Metric
+
+
+class AlignmentMetric(Metric):
+    read_name: str
+    mapping_quality: int
+    is_duplicate: bool = False
+
+
 from fgmetric import MetricWriter
 
 metrics = [

Alternatively, if the intent is to keep the class definition separate, import it from the earlier section (though this assumes readers have already executed that code block):

 ```python
+from pathlib import Path
+from fgmetric import Metric
+
+class AlignmentMetric(Metric):
+    read_name: str
+    mapping_quality: int
+    is_duplicate: bool = False
+
 from fgmetric import MetricWriter
 
 metrics = [
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/guide.md` around lines 67 - 77, The example uses AlignmentMetric and
Path but only imports MetricWriter, so make the snippet self-contained by either
(A) adding the missing import "from pathlib import Path", importing or defining
AlignmentMetric (e.g., declare class AlignmentMetric(Metric) with fields
read_name, mapping_quality, is_duplicate=False and import Metric from fgmetric)
before using MetricWriter, or (B) if AlignmentMetric is defined elsewhere, add
an explicit "from <module> import AlignmentMetric" import; ensure the metric
class name AlignmentMetric and the Path import are present so
MetricWriter(AlignmentMetric, Path("output.tsv")) and writer.writeall(metrics)
work when copy/pasted.

Comment thread mkdocs.yml
@@ -0,0 +1,63 @@
site_name: fgmetric
site_url: https://fgmetric.readthedocs.io/en/stable/
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

For MkDocs projects hosted on Read the Docs, what is the recommended site_url configuration for versioned builds and canonical URLs?

💡 Result:

For MkDocs projects on Read the Docs (including versioned builds), configure site_url to use Read the Docs’ per-build canonical URL:

# mkdocs.yml
site_url: !ENV READTHEDOCS_CANONICAL_URL

Read the Docs computes and exposes READTHEDOCS_CANONICAL_URL (taking into account your default version like latest/stable and any canonical custom domain) and recommends using it for MkDocs’ site_url, which MkDocs uses to emit canonical <link rel="canonical"> URLs. [1] [2] [3]


Use Read the Docs' canonical URL environment variable instead of hardcoding the stable URL.

Hardcoding site_url to the stable URL produces incorrect canonical links in versioned and preview builds. Read the Docs automatically provides READTHEDOCS_CANONICAL_URL (accounting for the default version and any custom domains), which should be used for site_url so MkDocs emits the correct <link rel="canonical"> tags.

Proposed change
-site_url: https://fgmetric.readthedocs.io/en/stable/
+site_url: !ENV [READTHEDOCS_CANONICAL_URL, "https://fgmetric.readthedocs.io/en/stable/"]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mkdocs.yml` at line 2, Replace the hardcoded site_url value with the Read the
Docs canonical URL environment variable: update the mkdocs configuration so that
the site_url key uses the READTHEDOCS_CANONICAL_URL environment variable (e.g.,
set site_url to the environment variable reference) instead of the fixed
"https://fgmetric.readthedocs.io/en/stable/" so MkDocs emits correct canonical
links for versioned and preview builds.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants